package com.rangers.manage.sms.core;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

import com.rangers.manage.sms.domain.YxDialBackReq;
import com.rangers.manage.sms.domain.YxNotifyCallReq;
import com.rangers.manage.sms.domain.YxProviderApiReq;
import com.rangers.manage.sms.domain.YxProviderApiRes;
import com.rangers.manage.sms.domain.YxProviderApilog;
import com.rangers.manage.sms.domain.YxProviderConfig;
import com.rangers.manage.sms.domain.YxTemSmsReq;

/**
 * 云讯通信供应商
 * 
 * {@link http://www.ytx.net/new_File/FileDailBackCall.aspx }
 * 
 * @author fuhw
 * @date 2017年11月20日
 */
public class YxCommunicateProvider implements InitializingBean {

	public static String PROVIDER_BASEURL = "http://api.ytx.net";

	/**
	 * 1.version,2.accountSID,3.func,4.funcURL,5.Sign
	 */
	private static String YX_API_URL_M = "/%s/sid/%s/%s/%s?Sign=%s";

	private static final Logger log = LoggerFactory.getLogger(YxCommunicateProvider.class);

	private final RestTemplate restTemplate;

	private final YxProviderConfig yxProviderConfig;

	public YxCommunicateProvider(RestTemplate restTemplate, YxProviderConfig yxProviderConfig) {
		super();
		this.restTemplate = restTemplate;
		this.yxProviderConfig = yxProviderConfig;
	}

	private static Map<Object, Object> resCodeMap;
	static {
		try {
			Properties loadAllProperties = PropertiesLoaderUtils.loadAllProperties("props/yx-api-rescode.properties");
			if (loadAllProperties != null) {
				resCodeMap = loadAllProperties;
			}
		} catch (IOException e) {
			log.debug("API数据接口响应码配置加载失败");
			throw new RuntimeException("API数据接口响应码配置加载失败");
		}
	}

//	public static void main(String[] args) {
//		YxProviderConfig yxProviderConfig = new YxProviderConfig("a15aaf5ddd434a4396cf90ae478e0f2e",
//				"b1d5809e9b1c4e129bcdad4d9e120e9c");
//		YxCommunicateProvider provider = new YxCommunicateProvider(new RestTemplate(), yxProviderConfig);
//		YxProviderApilog apilog = provider.executeTemSms(
//				new YxTemSmsReq("fe5f500cc2f549889aae08114c5e37ac", "13162952822","1345",new String[]{"455788"}));
//		System.err.println(apilog);
//	}

	/**
	 * 模板短信服务
	 */
	public YxProviderApilog executeTemSms(YxTemSmsReq yxTemSmsReq) {
		return this.execute(yxTemSmsReq, YxProviderConfig.FUNC_SMS, YxProviderConfig.FUNCURL_TEMPLATESMS);
	}

	/**
	 * 语音通知
	 */
	public YxProviderApilog executeNotifyCall(YxNotifyCallReq yxNotifyCallReq) {
		return this.execute(yxNotifyCallReq, YxProviderConfig.FUNC_CALL, YxProviderConfig.FUNCURL_NOTICEALL);
	}

	/**
	 * 双向通话
	 */
	public YxProviderApilog executeDialBack(YxDialBackReq yxDialBackReq) {
		return this.execute(yxDialBackReq, YxProviderConfig.FUNC_CALL, YxProviderConfig.FUNCURL_DAILBACK);
	}

	/**
	 * 执行通讯服务
	 *
	 * @param apiReq
	 * @param func
	 *            功能所属分类call【语音类】/sms【消息类】/traffic【流量类】/account【账户类】 当前功能属：call
	 *            {@link YxProviderConfig}
	 * @param funcURL
	 *            业务功能的各类具体操作分支 当前功能属：NoticeCall.wx {@link YxProviderConfig}
	 * @return 记录日志
	 * 
	 * @author fuhw
	 * @date 2017年11月20日 下午6:21:16
	 */
	public YxProviderApilog execute(YxProviderApiReq apiReq, String func, String funcURL) {
		log.info("通讯服务：==> start");
		Assert.hasText(func, "the func of commutication provider must be not null");
		Assert.hasText(funcURL, "the funcURL of commutication provider must be not null");
		String notifycallApiUrl = String.format(YX_API_URL_M, yxProviderConfig.getVersion(),
				yxProviderConfig.getAccountSID(), func, funcURL, yxProviderConfig.getSign());

		StringBuffer sb = new StringBuffer();
		sb.append(PROVIDER_BASEURL).append(notifycallApiUrl);
		log.info("通讯服务：==> url:{}", sb.toString());
		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.setContentType(MediaType.APPLICATION_JSON);
		httpHeaders.set("Authorization", yxProviderConfig.getAuthorization());
		HttpEntity<YxProviderApiReq> httpEntity = new HttpEntity<>(apiReq, httpHeaders);
		log.info("通讯服务：==> request-content:{}", httpEntity);
		YxProviderApiRes postForObject = restTemplate.postForObject(sb.toString(), httpEntity, YxProviderApiRes.class,
				httpHeaders);
		log.info("通讯服务：==> response:{}", postForObject);

		YxProviderApilog apilog = new YxProviderApilog(apiReq.getSrc(), apiReq.getDst(), funcURL);
		String statusCode = postForObject.getStatusCode();
		if (postForObject == null || "".equals(statusCode)) {
			throw new RuntimeException("通讯供应商服务器繁忙");
		} else if ("0".equals(statusCode)) {
			apilog.setStatusCode(statusCode);
			apilog.setStatusMsg(postForObject.getStatusMsg());
			apilog.setRequestId(postForObject.getRequestId());
		} else {
			log.error("通讯服务：==> failed:{}", resCodeMap.get(statusCode));
			throw new RuntimeException("通讯失败");
		}
		log.info("通讯服务：==> end");
		return apilog;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(restTemplate, "the restTemplate must be not null");
		Assert.notNull(yxProviderConfig, "the yxProviderConfig must be not null");
	}

}
